package com.pine.common.database;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.pine.common.database.annotations.DataPermission;
import com.pine.common.database.annotations.DataPermissionGroup;
import com.pine.common.database.constant.DbDataScopeEnum;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 基础mapper
 *
 * @author pine manage
 * @since 2024-08-09
 */
public interface BaseMapper<Entity> extends com.baomidou.mybatisplus.core.mapper.BaseMapper<Entity> {

    /**
     * 批量插入
     *
     * @param entityList 实体对象集合
     * @return 插入数量
     */
    @SuppressWarnings("all")
    int insertBatchSomeColumn(List<Entity> entityList);

    /**
     * 批量插入
     *
     * @param entityList 实体对象集合
     * @param batchSize  批次数量
     */
    @SuppressWarnings("all")
    default void insertBatchSomeColumn(List<Entity> entityList, int batchSize) {
        List<List<Entity>> splitArray = BaseMapper.split(entityList, batchSize);
        splitArray.forEach(this::insertBatchSomeColumn);
    }


    /**
     * 对集合按照指定长度分段，每一个段为单独的集合，返回这个集合的列表
     *
     * @param <T>        集合元素类型
     * @param collection 集合
     * @param size       每个段的长度
     * @return 分段列表
     */
    private static <T> List<List<T>> split(Collection<T> collection, int size) {
        final List<List<T>> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(collection)) {
            return result;
        }

        final int initSize = Math.min(collection.size(), size);
        List<T> subList = new ArrayList<>(initSize);
        for (T t : collection) {
            if (subList.size() >= size) {
                result.add(subList);
                subList = new ArrayList<>(initSize);
            }
            subList.add(t);
        }
        result.add(subList);
        return result;
    }

    /**
     * 根据 Wrapper 条件，判断是否存在记录
     *
     * @param queryWrapper 实体对象封装操作类
     * @return 是否存在记录
     */
    @DataPermissionGroup({
            @DataPermission(dataScope = DbDataScopeEnum.ONLY_SELF, permissionFieldName = "create_user_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT_WITH_CHILDREN, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.ALL)
    })
    default boolean exists(Wrapper<Entity> queryWrapper) {
        Long count = this.selectCount(queryWrapper);
        return null != count && count > 0;
    }

    /**
     * 根据 Wrapper 条件，查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    @DataPermissionGroup({
            @DataPermission(dataScope = DbDataScopeEnum.ONLY_SELF, permissionFieldName = "create_user_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT_WITH_CHILDREN, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.ALL)
    })
    Long selectCount(@Param(Constants.WRAPPER) Wrapper<Entity> queryWrapper);

    /**
     * 根据 entity 条件，查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     */
    @DataPermissionGroup({
            @DataPermission(dataScope = DbDataScopeEnum.ONLY_SELF, permissionFieldName = "create_user_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT_WITH_CHILDREN, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.ALL)
    })
    List<Entity> selectList(@Param(Constants.WRAPPER) Wrapper<Entity> queryWrapper);

    /**
     * 根据 entity 条件，查询全部记录
     *
     * @param queryWrapper  实体对象封装操作类（可以为 null）
     * @param resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */
    @DataPermissionGroup({
            @DataPermission(dataScope = DbDataScopeEnum.ONLY_SELF, permissionFieldName = "create_user_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT_WITH_CHILDREN, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.ALL)
    })
    void selectList(@Param(Constants.WRAPPER) Wrapper<Entity> queryWrapper, ResultHandler<Entity> resultHandler);

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page         分页查询条件
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @since 3.5.3.2
     */
    @DataPermissionGroup({
            @DataPermission(dataScope = DbDataScopeEnum.ONLY_SELF, permissionFieldName = "create_user_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT_WITH_CHILDREN, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.ALL)
    })
    List<Entity> selectList(IPage<Entity> page, @Param(Constants.WRAPPER) Wrapper<Entity> queryWrapper);

    /**
     * 根据 entity 条件，查询全部记录（并翻页）
     *
     * @param page          分页查询条件
     * @param queryWrapper  实体对象封装操作类（可以为 null）
     * @param resultHandler 结果处理器 {@link ResultHandler}
     * @since 3.5.4
     */
    @DataPermissionGroup({
            @DataPermission(dataScope = DbDataScopeEnum.ONLY_SELF, permissionFieldName = "create_user_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.DEPT_WITH_CHILDREN, permissionFieldName = "dept_id"),
            @DataPermission(dataScope = DbDataScopeEnum.ALL)
    })
    void selectList(IPage<Entity> page, @Param(Constants.WRAPPER) Wrapper<Entity> queryWrapper, ResultHandler<Entity> resultHandler);
}
